home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 6
/
FM Towns Free Software Collection 6.iso
/
ms_dos
/
dsort
/
dstqsrt.pre
< prev
Wrap
Text File
|
1993-07-08
|
6KB
|
187 lines
page 96,132
;§∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞§
;§ §
;§ ディレクトリエントリ ソート ユーティリティ §
;§ §
;§ DSORT.EXE Ver1.30 §
;§ §
;§ Copyright (C) by 福地 邦雄 1991-1992. All rights reserved. §
;§∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞§
.MODEL SMALL,C
;
REVERSE equ 1
FALSE equ 0
direntrysize equ 20h
direntryseg equ 2
;
public dirqsort,dirswap,sortfuncall
;
.code
;
;------------------------------------------------------------------------------
;
; dirqsort
; ディレクトリエントリのクイックソート
;
; TYPE near call
; IN [SP+2] = ソートバッファセグメント
; [SP+4] = 要素数
; ES:[SP+6] = 比較関数リストアドレス
; OUT なし
; 保存レジスタ bp,ds
;
;------------------------------------------------------------------------------
;
dirqsort proc sortobj,elmcount,funclist
local cmpobj,chgedobj,cmpcount,chgcount,funcseg
;
mov funcseg,es
qsorthead:
cmp elmcount,1
@if (zf,off),and,(cf,off),L ; 要素数2以上ならソート実行
mov dx,sortobj
add dx,direntryseg
cmp elmcount,02
mov cmpobj,dx
@if (zf,on) ; 要素数2なら直接比較
mov bx,funclist
mov es,funcseg
mov ds,sortobj
call sortfuncall
test ax,ax
@if (zf,off),and,(sf,off) ; エントリ1が大きい時は入れ換え
mov es,cmpobj
mov ds,sortobj
call dirswap
@ifend
@else ; 要素数3以上
mov ax,elmcount ; 比較の基準を配列の真ん中から取り出す
and ax,0fffeh
add ax,sortobj
mov es,ax
mov ds,sortobj
call dirswap
mov ax,sortobj ; 準備
mov chgcount,0
mov cmpcount,1
mov chgedobj,ax
@do repeat
mov ax,cmpcount ; 比較終了か?
@if (ax,>=,elmcount)
@doexit
@ifend
mov dx,sortobj ; 比較関数呼び出し
mov ds,cmpobj
mov bx,funclist
mov es,funcseg
call sortfuncall
test ax,ax
@if (sf,on) ; 比較対象エントリが小さい時
inc chgcount
add chgedobj,direntryseg
mov si,cmpobj
mov es,si
mov di,chgedobj
mov ds,di
@if (si,/=,di)
call dirswap
@ifend
@ifend
add cmpobj,direntryseg ; 次の比較対象へ
inc cmpcount
@doend
mov di,sortobj ;
mov ds,di
mov si,chgedobj
mov es,si
@if (si,/=,di)
call dirswap
@ifend
mov bx,chgedobj ; 再帰呼び出し準備
add bx,direntryseg
mov cx,elmcount
mov ax,chgcount
sub cx,ax
dec cx
@if (cx,>,ax),S ; エントリ数の少ない方によって環境を整える
mov elmcount,cx ; 入れ換え済の方が少ない
mov cx,ax
xchg bx,sortobj
@else
mov elmcount,ax ; 入れ換え無しの方が少ない
@ifend
@if (cx,>,1) ; 要素数2以上なら
mov es,funcseg ;
push funclist ; 再帰呼び出し(エントリの少ない方)
push cx
push bx
call dirqsort
@ifend
jmp qsorthead ; 末尾再帰呼び出し(ループ)
@ifend
@ifend
ret 6
;
dirqsort endp
;
;------------------------------------------------------------------------------
;
; dirswap
; ディレクトリエントリの交換
;
; TYPE near call
; IN DS:0 = エントリ1アドレス
; ES:0 = エントリ2アドレス
; OUT なし
; 保存レジスタ bx,dx,di,bp,ds,es
;
;------------------------------------------------------------------------------
;
dirswap proc
;
mov cx,direntrysize/2
xor si,si
swaploop:
mov ax,[si]
xchg es:[si],ax
mov [si],ax
lea si,[si+2]
loop swaploop
;
ret
;
dirswap endp
;
;------------------------------------------------------------------------------
;
; sortfuncall
; ソート用比較関数列の呼び出し
;
; TYPE near call
; IN ES:BX = 比較関数列のアドレス
; DS:0 = エントリ1アドレス
; DX:0 = エントリ2アドレス
; OUT AX = 比較結果
; 保存レジスタ si,di,bp,ds,es
;
;------------------------------------------------------------------------------
;
sortfuncall proc
;
@do until
call word ptr es:[bx] ; 比較関数呼び出し
@if (word ptr es:[bx+2],=,REVERSE) ; 逆順指定の時は結果を反転
neg ax
@ifend
@if (ax,/=,0) ; 比較して違いがあれば終了
jmp compareend
@ifend
lea bx,[bx+4] ; 次の比較関数へ
@doend (word ptr es:[bx],=,0) ; 関数列の終了まで
compareend:
ret
;
sortfuncall endp
;
end